﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;

namespace ElfKit.Common.Collections
{
    public static class EqualityComparerFactory
    {
        private static readonly Dictionary<RuntimeTypeHandle, IEqualityComparer> TypeToComparerMap = CreateTypeToComparerMap();

        public static IEqualityComparer Create(Type type)
        {
            Guard.NotNull(type, nameof(type));

            if (TypeToComparerMap.TryGetValue(type.TypeHandle, out IEqualityComparer comparer))
            {
                return comparer;
            }

            if (type.IsEnum)
            {
                return new EnumEqualityComparer();
            }

            if (type == typeof(string))
            {
                return StringComparer.Create(Env.GetCurrentCulture(), false);
            }

            if (typeof(IEnumerable).IsAssignableFrom(type))
            {
            }

            PropertyInfo[] pis = type.GetProperties(Constant.BindingAttributes.InstancePublic).OrderBy(p => p.Name).ToArray();
            foreach (PropertyInfo pi in pis)
            {
                Type propertyType = pi.PropertyType;
                IEqualityComparer propComparer = Create(propertyType);
            }

            return null;
        }

        #region CreateTypeToComparerMap

        /// <summary>
        /// 建立类型与<see cref="IEqualityComparer"/>映射.
        /// </summary>
        /// <returns>类型与<see cref="IEqualityComparer"/>映射.</returns>
        private static Dictionary<RuntimeTypeHandle, IEqualityComparer> CreateTypeToComparerMap()
        {
            return new Dictionary<RuntimeTypeHandle, IEqualityComparer>()
            {
                { typeof(int).TypeHandle,EqualityComparer<int>.Default  },
                { typeof(uint).TypeHandle,EqualityComparer<uint>.Default  },
                { typeof(long).TypeHandle,EqualityComparer<long>.Default  },
                { typeof(ulong).TypeHandle,EqualityComparer<ulong>.Default  },
                { typeof(short).TypeHandle,EqualityComparer<short>.Default  },
                { typeof(ushort).TypeHandle,EqualityComparer<ushort>.Default  },
                { typeof(byte).TypeHandle,EqualityComparer<byte>.Default  },
                { typeof(sbyte).TypeHandle,EqualityComparer<sbyte>.Default  },
                { typeof(float).TypeHandle,EqualityComparer<float>.Default  },
                { typeof(double).TypeHandle,EqualityComparer<double>.Default  },
                { typeof(decimal).TypeHandle,EqualityComparer<decimal>.Default  },
                { typeof(bool).TypeHandle,EqualityComparer<bool>.Default  },
                { typeof(char).TypeHandle,EqualityComparer<char>.Default  },
                { typeof(DateTime).TypeHandle,EqualityComparer<DateTime>.Default  },
                { typeof(TimeSpan).TypeHandle,EqualityComparer<TimeSpan>.Default  },
                { typeof(DateTimeOffset).TypeHandle,EqualityComparer<DateTimeOffset>.Default  },
            };
        }

        #endregion

        #region EnumEqualityComparer

        /// <summary>
        /// 枚举相等比较器.
        /// </summary>
        private sealed class EnumEqualityComparer : IEqualityComparer
        {
            /// <inheritdoc/>
            public new bool Equals(object x, object y)
            {
                return CompareUtil.HashCodeAreEqual(x, y, this.GetHashCode);
            }

            /// <inheritdoc/>
            public int GetHashCode(object obj)
            {
                return Convert.ToInt64(obj, CultureInfo.InvariantCulture).GetHashCode();
            }
        }

        #endregion
    }
}